package torres;


import java.io.File;
import java.io.IOException;
import javax.swing.JOptionPane;

import torres.map.*;
import torres.map.effect.AreaEffect;
import torres.view.*;
import torres.controller.Controller;
import torres.entity.*;
import torres.fileIO.Saver;
import torres.item.ItemManager;


public class RunGame {
	
	public static Avatar player;
	public static boolean load;
	public static int moveCounter = 0;
	

	/**
	 * @author Torres
	 *
	 */
	enum OccupationEnum {
		SMASHER, SUMMONER, SNEAK;
		
		@Override 
		public String toString() {
   			String s = super.toString();
  			return s.substring(0, 1) + s.substring(1).toLowerCase();
 		}
	}
	
	public static void main(String[] args) {
		
		while(true) {
			
			File itemFile;
			load = false;
			
			try{
			    
				String[] buttons = { "New Game", "Load Game"};

			    int choice = -1;
			    while(choice == -1) {
				    
			    	choice = JOptionPane.showOptionDialog(null, "Main Menu", "Main Menu",
				        JOptionPane.INFORMATION_MESSAGE, 1, null, buttons, buttons[0]);
			    	
				    if(choice == 1) {
				    	
				    	try {
				    		
				    		Saver.load("save1.sav");
				    	}
				    	catch(IOException e) {
				    		
				    		choice = -1;
				    	}
				    }
				    else if(choice != 0)
				    	System.exit(1);
			    }
				if(choice == 1) {
					
					Saver.load("save1.sav");
				}
				else {
					
					//allow the player to choose a name
					String name = null;
					while(name==null) {
						
						name = JOptionPane.showInputDialog(null, "Name: ");
						if(name == null)
							System.exit(1);
						
					}
					
					//allow the player to choose an occupation and create the avatar
					OccupationEnum occupation = null;
					while(occupation==null) {
						OccupationEnum[] selectionValues = {OccupationEnum.SMASHER, 
													OccupationEnum.SUMMONER,
													OccupationEnum.SNEAK};
					    OccupationEnum initialSelection = OccupationEnum.SMASHER;
					    occupation = (OccupationEnum) JOptionPane.showInputDialog(null, "Occupation?",
					        "Occupation", JOptionPane.QUESTION_MESSAGE, null, selectionValues, initialSelection);
					    
					    
					    if(occupation == null)
					    	System.exit(1);
					}
					char c = 169;
				    switch(occupation) {
				    	
				    	case SMASHER:
				    		player = new Avatar(c + "", new Smasher(), new Location(2,4));
							break;
						case SUMMONER:
				    		player = new Avatar(c + "", new Summoner(), new Location(2,4));
				    		break;
				    	case SNEAK:	
				    		player = new Avatar(c + "", new Sneak(), new Location(2,4));
				    		break;
				    }
				    player.setFullName(name);
				    
				    //parse the items file
					itemFile = new File("src/resources/items/items.txt");
					ItemManager itemManager = ItemManager.getInstance();
					itemManager.generate(itemFile);
					
					//add maps to the world
					File mapFile1 = new File("src/resources/maps/map1.map");
					File mapFile2 = new File("src/resources/maps/map2.map");
					File mapFile3 = new File("src/resources/maps/map3.map");
					Map map1 = new Map(mapFile1, "map1", player);
					Map map2 = new Map(mapFile2, "map2", null);
					Map map3 = new Map(mapFile3, "map3", null);
					World.getInstance().addMap(map1);
					World.getInstance().addMap(map2);
					World.getInstance().addMap(map3);
					World.getInstance().setCurrentMap(map1);
					
					//add the player to the map/world
					map1.getTiles()[player.getLocation().getY()][player.getLocation().getX()].addEntity(player);
				}
				
				//initialize the viewport(s)
				MainView mainView = new MainView();
				mainView.getAreaViewPort().setCurrentMap(World.getInstance().getCurrentMap());
				player = World.getInstance().getCurrentMap().getAvatar();
				Controller.addKeyListener(mainView);
				Controller.addMouseListener(mainView);
				
				long start = 0, elapsed = 0;
				long required = 1000000000;
				
				//begin game loop
				while(player.getLivesLeft()!=0) {
					if(load) {
						try {
							Saver.load("save1.sav");
						}
						catch (IOException ioe) { ioe.toString(); }
						
						player = World.getInstance().getCurrentMap().getAvatar();
						load = false;
					}
					
					//apply area effects to the player
					Location playerLocation = player.getLocation();
					Map currMap = World.getInstance().getCurrentMap();
					if(currMap.hasEffect(playerLocation)) {
						
						AreaEffect effect = currMap.getEffect(playerLocation);
						if(elapsed >= required * effect.getMultiplier()) {
							
							effect.applyEffect(player);
							elapsed = 0;
							start = System.nanoTime();
						}
						else {
							elapsed += System.nanoTime() - start;
						}
					}
					
					//try to move the player and/or re-draw the viewport
					Long time1 = System.nanoTime();
					mainView.draw();
					if(moveCounter>0)
						moveCounter -= 10;
					else
						moveCounter = 0;
					Long difference = System.nanoTime()-time1;
					difference /= 1000000;
					difference = 68 - difference;
					try {
						
						if(difference>0) {
							
							Thread.sleep(difference);
						}
					}
					catch(InterruptedException exception) { 
						
						exception.printStackTrace(); 
					}
				} //end of game loop
				
				//display restart prompt when the player dies
				mainView.dispose();
				int option = JOptionPane.showConfirmDialog(null, "Restart?", "You just died!", JOptionPane.YES_NO_OPTION);
				if(Math.abs(option)==1) {
					
					System.exit(0);
					break;
				}
				World.getInstance().getCurrentMap().removeAvatar();
			}
			catch(Exception e) {
				
				e.printStackTrace();
			}
		}
	}
}
